library(stringr)
library(tidyverse)
library(bigrquery)
library(MuMIn)
response <- try(system('~/google-cloud-sdk/bin/gcloud projects list --quiet', intern = T))
projectid <- strsplit(response[2], " ")[[1]][1]
options(na.action = "na.fail") 
source("./dredge_functions.R")
dredge_and_subset <- function(data) {
  model <- lm(
    response ~ foraging_niche + trophic_niche + is_nocturnal + pc1 + pc2 + pc3 + pc4 + total_species,
    data=data
  )
  dredge_result <- dredge(model)
  summary(model.avg(dredge_result, subset = delta < 10))
}
load_niche_data <- function() {
  filename <- 'species_analysis_cache.csv'
  
  if (!file.exists(filename)) {
    
    sql <- "
        SELECT 
          niche_name,
          foraging_niche, 
          trophic_niche, 
          is_noctural, 
          total_species,
          merlin_10_perc_ratio, 
          merlin_20_perc_ratio, 
          birdlife_10_perc_ratio, 
          birdlife_20_perc_ratio, 
          either_10_perc_ratio, 
          either_20_perc_ratio, 
          both_10_perc_ratio, 
          both_20_perc_ratio, 
          body_morphspace.pc1.mean AS pc1, 
          body_morphspace.pc2.mean AS pc2, 
          body_morphspace.pc3.mean AS pc3, 
          body_morphspace.pc4.mean AS pc4
        FROM `endless-matter-297214.model2.niche_analysis_model` LIMIT 1000 
    "
  
    tb <- bq_project_query(projectid, sql)

    data <- bq_table_download(tb)
    write_csv(data, filename)
  }
  
  data <- read_csv(filename)
  
  data[is.na(data$foraging_niche),]$foraging_niche <- 'Omnivore'
  
  data$foraging_niche = as.factor(data$foraging_niche)
  data$trophic_niche = as.factor(data$trophic_niche)
  data$is_nocturnal = as.factor(data$is_noctural)
  
  data
}

data_for_response <- function(column_name_for_response) {
  data <- load_niche_data()
  names(data)[names(data) == column_name_for_response] <- "response"
  
  data[,c("niche_name", "response", "foraging_niche", "trophic_niche", "is_nocturnal", "pc1", "pc2", "pc3", "pc4", "total_species")]
}
0.25 Percentile - 10% of species
merlin_10_data <- data_for_response('merlin_10_perc_ratio')

── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
cols(
  niche_name = col_character(),
  foraging_niche = col_character(),
  trophic_niche = col_character(),
  is_noctural = col_logical(),
  total_species = col_double(),
  merlin_10_perc_ratio = col_double(),
  merlin_20_perc_ratio = col_double(),
  birdlife_10_perc_ratio = col_double(),
  birdlife_20_perc_ratio = col_double(),
  either_10_perc_ratio = col_double(),
  either_20_perc_ratio = col_double(),
  both_10_perc_ratio = col_double(),
  both_20_perc_ratio = col_double(),
  pc1 = col_double(),
  pc2 = col_double(),
  pc3 = col_double(),
  pc4 = col_double()
)
merlin_10_data
merlin_10_result <- dredge_and_subset(merlin_10_data)
Fixed term is "(Intercept)"
merlin_10_summ <- model_summary('merlin_10', 'species', merlin_10_result)
merlin_10_summ
birdlife_10_data <- data_for_response('birdlife_10_perc_ratio')

── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
cols(
  niche_name = col_character(),
  foraging_niche = col_character(),
  trophic_niche = col_character(),
  is_noctural = col_logical(),
  total_species = col_double(),
  merlin_10_perc_ratio = col_double(),
  merlin_20_perc_ratio = col_double(),
  birdlife_10_perc_ratio = col_double(),
  birdlife_20_perc_ratio = col_double(),
  either_10_perc_ratio = col_double(),
  either_20_perc_ratio = col_double(),
  both_10_perc_ratio = col_double(),
  both_20_perc_ratio = col_double(),
  pc1 = col_double(),
  pc2 = col_double(),
  pc3 = col_double(),
  pc4 = col_double()
)
birdlife_10_result <- dredge_and_subset(birdlife_10_data)
Fixed term is "(Intercept)"
birdlife_10_summ <- model_summary('birdlife_10', 'species', birdlife_10_result)
birdlife_10_summ
both_10_data <- data_for_response('both_10_perc_ratio')

── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
cols(
  niche_name = col_character(),
  foraging_niche = col_character(),
  trophic_niche = col_character(),
  is_noctural = col_logical(),
  total_species = col_double(),
  merlin_10_perc_ratio = col_double(),
  merlin_20_perc_ratio = col_double(),
  birdlife_10_perc_ratio = col_double(),
  birdlife_20_perc_ratio = col_double(),
  either_10_perc_ratio = col_double(),
  either_20_perc_ratio = col_double(),
  both_10_perc_ratio = col_double(),
  both_20_perc_ratio = col_double(),
  pc1 = col_double(),
  pc2 = col_double(),
  pc3 = col_double(),
  pc4 = col_double()
)
both_10_result <- dredge_and_subset(both_10_data)
Fixed term is "(Intercept)"
both_10_summ <- model_summary('both_10', 'species', both_10_result)
both_10_summ
either_10_data <- data_for_response('either_10_perc_ratio')

── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
cols(
  niche_name = col_character(),
  foraging_niche = col_character(),
  trophic_niche = col_character(),
  is_noctural = col_logical(),
  total_species = col_double(),
  merlin_10_perc_ratio = col_double(),
  merlin_20_perc_ratio = col_double(),
  birdlife_10_perc_ratio = col_double(),
  birdlife_20_perc_ratio = col_double(),
  either_10_perc_ratio = col_double(),
  either_20_perc_ratio = col_double(),
  both_10_perc_ratio = col_double(),
  both_20_perc_ratio = col_double(),
  pc1 = col_double(),
  pc2 = col_double(),
  pc3 = col_double(),
  pc4 = col_double()
)
either_10_result <- dredge_and_subset(either_10_data)
Fixed term is "(Intercept)"
either_10_summ <- model_summary('either_10', 'species', either_10_result)
either_10_summ
Full result for 10% of species
all_species_results <- full_join(full_join(merlin_10_summ, birdlife_10_summ), full_join(both_10_summ, either_10_summ))
Joining, by = c("explanatory", "model")
Joining, by = c("explanatory", "model")
Joining, by = c("explanatory", "model")
write_csv(all_species_results, "species_analysis_result_10_perc.csv")
0.75 Percentile - 20% of species
merlin_20_data <- data_for_response('merlin_20_perc_ratio')

── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
cols(
  niche_name = col_character(),
  foraging_niche = col_character(),
  trophic_niche = col_character(),
  is_noctural = col_logical(),
  total_species = col_double(),
  merlin_10_perc_ratio = col_double(),
  merlin_20_perc_ratio = col_double(),
  birdlife_10_perc_ratio = col_double(),
  birdlife_20_perc_ratio = col_double(),
  either_10_perc_ratio = col_double(),
  either_20_perc_ratio = col_double(),
  both_10_perc_ratio = col_double(),
  both_20_perc_ratio = col_double(),
  pc1 = col_double(),
  pc2 = col_double(),
  pc3 = col_double(),
  pc4 = col_double()
)
merlin_20_result <- dredge_and_subset(merlin_20_data)
Fixed term is "(Intercept)"
merlin_20_summ <- model_summary('merlin_20', 'species', merlin_20_result)
merlin_20_summ
birdlife_20_data <- data_for_response('birdlife_20_perc_ratio')

── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
cols(
  niche_name = col_character(),
  foraging_niche = col_character(),
  trophic_niche = col_character(),
  is_noctural = col_logical(),
  total_species = col_double(),
  merlin_10_perc_ratio = col_double(),
  merlin_20_perc_ratio = col_double(),
  birdlife_10_perc_ratio = col_double(),
  birdlife_20_perc_ratio = col_double(),
  either_10_perc_ratio = col_double(),
  either_20_perc_ratio = col_double(),
  both_10_perc_ratio = col_double(),
  both_20_perc_ratio = col_double(),
  pc1 = col_double(),
  pc2 = col_double(),
  pc3 = col_double(),
  pc4 = col_double()
)
birdlife_20_result <- dredge_and_subset(birdlife_20_data)
Fixed term is "(Intercept)"
birdlife_20_summ <- model_summary('birdlife_20', 'species', birdlife_20_result)
birdlife_20_summ
both_20_data <- data_for_response('both_20_perc_ratio')

── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
cols(
  niche_name = col_character(),
  foraging_niche = col_character(),
  trophic_niche = col_character(),
  is_noctural = col_logical(),
  total_species = col_double(),
  merlin_10_perc_ratio = col_double(),
  merlin_20_perc_ratio = col_double(),
  birdlife_10_perc_ratio = col_double(),
  birdlife_20_perc_ratio = col_double(),
  either_10_perc_ratio = col_double(),
  either_20_perc_ratio = col_double(),
  both_10_perc_ratio = col_double(),
  both_20_perc_ratio = col_double(),
  pc1 = col_double(),
  pc2 = col_double(),
  pc3 = col_double(),
  pc4 = col_double()
)
both_20_result <- dredge_and_subset(both_20_data)
Fixed term is "(Intercept)"
both_20_summ <- model_summary('both_20', 'species', both_20_result)
both_20_summ
either_20_data <- data_for_response('either_20_perc_ratio')

── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
cols(
  niche_name = col_character(),
  foraging_niche = col_character(),
  trophic_niche = col_character(),
  is_noctural = col_logical(),
  total_species = col_double(),
  merlin_10_perc_ratio = col_double(),
  merlin_20_perc_ratio = col_double(),
  birdlife_10_perc_ratio = col_double(),
  birdlife_20_perc_ratio = col_double(),
  either_10_perc_ratio = col_double(),
  either_20_perc_ratio = col_double(),
  both_10_perc_ratio = col_double(),
  both_20_perc_ratio = col_double(),
  pc1 = col_double(),
  pc2 = col_double(),
  pc3 = col_double(),
  pc4 = col_double()
)
either_20_result <- dredge_and_subset(either_20_data)
Fixed term is "(Intercept)"
either_20_summ <- model_summary('either_20', 'species', either_20_result)
either_20_summ
Full result for 10% of species
all_species_results <- full_join(full_join(merlin_20_summ, birdlife_20_summ), full_join(both_20_summ, either_20_summ))
Joining, by = c("explanatory", "model")
Joining, by = c("explanatory", "model")
Joining, by = c("explanatory", "model")
write_csv(all_species_results, "species_analysis_result_20_perc.csv")
Comparing the 2 percentiles
ggplot(merlin_10_data, aes(x = response)) + geom_bar(width = 0.1)
Warning: position_stack requires non-overlapping x intervals

bind_sets <- function(first_percentile, second_percentile) {
  first_percentile$percentile <- "0.25"
  second_percentile$percentile <- "0.75"
  rbind(first_percentile, second_percentile)
}

merlin_species_data <- bind_sets(merlin_10_data,  merlin_20_data)
birdlife_species_data <- bind_sets(birdlife_10_data,  birdlife_20_data)
either_species_data <- bind_sets(either_10_data,  either_20_data)
both_species_data <- bind_sets(both_10_data,  both_20_data)
ggplot(merlin_species_data, aes(x = response, y = trophic_niche, color = percentile)) + geom_boxplot() + theme_bw()

merlin_trophic_niche_niche_anova <- aov(response~trophic_niche + percentile + Error(niche_name), data=merlin_species_data)
summary(merlin_trophic_niche_niche_anova)

Error: niche_name
               Df Sum Sq Mean Sq F value Pr(>F)  
trophic_niche   9  1.762  0.1958   1.679 0.0943 .
Residuals     258 30.084  0.1166                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Error: Within
            Df Sum Sq Mean Sq F value   Pr(>F)    
percentile   1  1.508  1.5077   59.65 2.29e-13 ***
Residuals  267  6.749  0.0253                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
merlin_trophic_niche_niche_anova_i <- aov(response~trophic_niche * percentile + Error(niche_name), data=merlin_species_data)
summary(merlin_trophic_niche_niche_anova_i)

Error: niche_name
               Df Sum Sq Mean Sq F value Pr(>F)  
trophic_niche   9  1.762  0.1958   1.679 0.0943 .
Residuals     258 30.084  0.1166                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Error: Within
                          Df Sum Sq Mean Sq F value   Pr(>F)    
percentile                 1  1.508  1.5077  69.821 4.05e-15 ***
trophic_niche:percentile   9  1.177  0.1308   6.057 1.03e-07 ***
Residuals                258  5.571  0.0216                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
pairwise.wilcox.test(merlin_diff_data$increase, merlin_diff_data$trophic_niche)
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
  cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
  cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
  cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
  cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
  cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
  cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
  cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
  cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
  cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
  cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
  cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
  cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
  cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
  cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
  cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
  cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
  cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
  cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
  cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
  cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
  cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
  cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
  cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
  cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
  cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
  cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
  cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
  cannot compute exact p-value with ties

    Pairwise comparisons using Wilcoxon rank sum test with continuity correction 

data:  merlin_diff_data$increase and merlin_diff_data$trophic_niche 

                      Aquatic predator Frugivore Granivore Herbivore aquatic Herbivore terrestrial Invertivore Nectarivore Omnivore Scavenger
Frugivore             0.5331           -         -         -                 -                     -           -           -        -        
Granivore             1.0000           1.0000    -         -                 -                     -           -           -        -        
Herbivore aquatic     1.0000           0.1167    1.0000    -                 -                     -           -           -        -        
Herbivore terrestrial 1.0000           1.0000    1.0000    1.0000            -                     -           -           -        -        
Invertivore           0.0076           1.0000    1.0000    0.0051            1.0000                -           -           -        -        
Nectarivore           1.0000           1.0000    1.0000    1.0000            1.0000                1.0000      -           -        -        
Omnivore              0.2684           1.0000    1.0000    0.0679            1.0000                1.0000      1.0000      -        -        
Scavenger             1.0000           1.0000    1.0000    1.0000            1.0000                1.0000      1.0000      1.0000   -        
Vertivore             1.0000           1.0000    1.0000    0.5929            1.0000                1.0000      1.0000      1.0000   1.0000   

P value adjustment method: holm 
library(multcomp)
merlin_increase_tropic_niche_anova <-aov(increase~trophic_niche, data=merlin_diff_data)
summary(merlin_increase_tropic_niche_anova)
               Df Sum Sq Mean Sq F value   Pr(>F)    
trophic_niche   9  3.941  0.4379   3.689 0.000229 ***
Residuals     258 30.629  0.1187                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
merlin_increase_tropic_niche_tukey <- cld(glht(merlin_increase_tropic_niche_anova, linfct=mcp(trophic_niche="Tukey")))
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
merlin_increase_tropic_niche_tukey
     Aquatic predator             Frugivore             Granivore     Herbivore aquatic Herbivore terrestrial           Invertivore           Nectarivore              Omnivore 
                 "bc"                  "ab"                  "ac"                   "c"                  "ac"                   "a"                  "ac"                  "ab" 
            Scavenger             Vertivore 
                 "ac"                  "ac" 
plot(merlin_increase_tropic_niche_tukey)

with.tukey.label.as.group <- function(tukey, dataset, join_by) {
  labels <- data.frame(tukey$mcletters$Letters)
  labels$category <- rownames(labels)
  colnames(labels) <- c("group", "category")
  
  
  left_join(dataset, labels, by = join_by)
}

ggplot(birdlife_species_data, aes(x = response, y = trophic_niche, color = percentile)) + geom_boxplot() + theme_bw()

birdlife_trophic_niche_niche_anova <- aov(response~trophic_niche + percentile + Error(niche_name), data=birdlife_species_data)
summary(birdlife_trophic_niche_niche_anova)

Error: niche_name
               Df Sum Sq Mean Sq F value Pr(>F)
trophic_niche   9  1.696  0.1885   1.605  0.114
Residuals     258 30.292  0.1174               

Error: Within
            Df Sum Sq Mean Sq F value   Pr(>F)    
percentile   1  1.327  1.3274   60.18 1.84e-13 ***
Residuals  267  5.890  0.0221                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
birdlife_trophic_niche_niche_anova_i <- aov(response~trophic_niche * percentile + Error(niche_name), data=birdlife_species_data)
summary(birdlife_trophic_niche_niche_anova_i)

Error: niche_name
               Df Sum Sq Mean Sq F value Pr(>F)
trophic_niche   9  1.696  0.1885   1.605  0.114
Residuals     258 30.292  0.1174               

Error: Within
                          Df Sum Sq Mean Sq F value   Pr(>F)    
percentile                 1  1.327  1.3274  64.018 4.19e-14 ***
trophic_niche:percentile   9  0.540  0.0600   2.893  0.00282 ** 
Residuals                258  5.350  0.0207                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
birdlife_increase_tropic_niche_anova <-aov(increase~trophic_niche, data=birdlife_diff_data)
summary(birdlife_increase_tropic_niche_anova)
               Df Sum Sq Mean Sq F value Pr(>F)  
trophic_niche   9   2.21  0.2453   1.791 0.0703 .
Residuals     258  35.35  0.1370                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
birdlife_increase_tropic_niche_tukey <- cld(glht(birdlife_increase_tropic_niche_anova, linfct=mcp(trophic_niche="Tukey")))
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
birdlife_increase_tropic_niche_tukey
     Aquatic predator             Frugivore             Granivore     Herbivore aquatic Herbivore terrestrial           Invertivore           Nectarivore              Omnivore 
                  "b"                  "ab"                  "ab"                  "ab"                  "ab"                   "a"                  "ab"                  "ab" 
            Scavenger             Vertivore 
                 "ab"                  "ab" 

ggplot(either_species_data, aes(x = response, y = trophic_niche, color = percentile)) + geom_boxplot() + theme_bw()

ggplot(both_species_data, aes(x = response, y = trophic_niche, color = percentile)) + geom_boxplot() + theme_bw()

nrow(merlin_10_data[merlin_10_data$response > 0,])
[1] 96
nrow(merlin_20_data[merlin_20_data$response > 0,])
[1] 128
nrow(birdlife_10_data[birdlife_10_data$response > 0,])
[1] 87
nrow(birdlife_20_data[birdlife_20_data$response > 0,])
[1] 124
nrow(either_10_data[either_10_data$response > 0,])
[1] 94
nrow(either_20_data[either_20_data$response > 0,])
[1] 123
nrow(both_10_data[both_10_data$response > 0,])
[1] 91
nrow(both_20_data[both_20_data$response > 0,])
[1] 128
ggplot(merlin_species_data, aes(x = response, y = foraging_niche, color = percentile)) + geom_boxplot() + theme_bw()

interaction.plot(merlin_species_data$foraging_niche, merlin_species_data$percentile, merlin_species_data$response)

merlin_foraging_niche_anova <- aov(response~foraging_niche + percentile + Error(niche_name), data=merlin_species_data)
summary(merlin_foraging_niche_anova)

Error: niche_name
                Df Sum Sq Mean Sq F value Pr(>F)
foraging_niche  32  4.894  0.1529   1.333  0.118
Residuals      235 26.952  0.1147               

Error: Within
            Df Sum Sq Mean Sq F value   Pr(>F)    
percentile   1  1.508  1.5077   59.65 2.29e-13 ***
Residuals  267  6.749  0.0253                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
merlin_foraging_niche_anova_i <- aov(response~foraging_niche * percentile + Error(niche_name), data=merlin_species_data)
summary(merlin_foraging_niche_anova_i)

Error: niche_name
                Df Sum Sq Mean Sq F value Pr(>F)
foraging_niche  32  4.894  0.1529   1.333  0.118
Residuals      235 26.952  0.1147               

Error: Within
                           Df Sum Sq Mean Sq F value   Pr(>F)    
percentile                  1  1.508  1.5077  68.706 8.81e-15 ***
foraging_niche:percentile  32  1.591  0.0497   2.266 0.000275 ***
Residuals                 235  5.157  0.0219                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
merlin_increase_foraging_niche_anova <-aov(increase~foraging_niche, data=merlin_diff_data)
summary(merlin_increase_foraging_niche_anova)
                Df Sum Sq Mean Sq F value Pr(>F)  
foraging_niche  32  5.804  0.1814   1.482 0.0533 .
Residuals      235 28.766  0.1224                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
merlin_increase_foraging_niche_tukey <- cld(glht(merlin_increase_foraging_niche_anova, linfct=mcp(foraging_niche="Tukey")))
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
merlin_increase_foraging_niche_tukey
            Aquatic aerial               Aquatic dive             Aquatic ground              Aquatic perch             Aquatic plunge            Aquatic surface            Fugivore aerial 
                       "a"                        "a"                        "a"                        "a"                        "a"                        "a"                        "a" 
            Fugivore glean            Fugivore ground                 Generalist         Granivore arboreal           Granivore ground     Herbivore aquatic dive   Herbivore aquatic ground 
                       "a"                        "a"                        "a"                        "a"                        "a"                        "a"                        "a" 
 Herbivore aquatic surface         Herbivore arboreal           Herbivore ground         Invertivore aerial           Invertivore bark Invertivore glean arboreal         Invertivore ground 
                       "a"                        "a"                        "a"                        "a"                        "a"                        "a"                        "a" 
     Invertivore sally air   Invertivore sally ground  Invertivore sally surface         Nectarivore aerial          Nectarivore glean                   Omnivore           Scavenger ground 
                       "a"                        "a"                        "a"                        "a"                        "a"                        "a"                        "a" 
          Vertivore aerial   Vertivore air to surface         Vertivore arboreal           Vertivore ground            Vertivore perch 
                       "a"                        "a"                        "a"                        "a"                        "a" 

ggplot(birdlife_species_data, aes(x = response, y = foraging_niche, color = percentile)) + geom_boxplot() + theme_bw()

birdlife_foraging_niche_anova <- aov(response~foraging_niche + percentile + Error(niche_name), data=birdlife_species_data)
summary(birdlife_foraging_niche_anova)

Error: niche_name
                Df Sum Sq Mean Sq F value Pr(>F)  
foraging_niche  32  5.519  0.1725   1.531 0.0401 *
Residuals      235 26.470  0.1126                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Error: Within
            Df Sum Sq Mean Sq F value   Pr(>F)    
percentile   1  1.327  1.3274   60.18 1.84e-13 ***
Residuals  267  5.890  0.0221                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
birdlife_foraging_niche_anova_i <- aov(response~foraging_niche * percentile + Error(niche_name), data=birdlife_species_data)
summary(birdlife_foraging_niche_anova_i)

Error: niche_name
                Df Sum Sq Mean Sq F value Pr(>F)  
foraging_niche  32  5.519  0.1725   1.531 0.0401 *
Residuals      235 26.470  0.1126                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Error: Within
                           Df Sum Sq Mean Sq F value   Pr(>F)    
percentile                  1  1.327  1.3274  67.870 1.22e-14 ***
foraging_niche:percentile  32  1.293  0.0404   2.066  0.00118 ** 
Residuals                 235  4.596  0.0196                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
birdlife_increase_foraging_niche_anova <-aov(increase~foraging_niche, data=birdlife_diff_data)
summary(birdlife_increase_foraging_niche_anova)
                Df Sum Sq Mean Sq F value Pr(>F)
foraging_niche  32   4.85  0.1517    1.09  0.347
Residuals      235  32.71  0.1392               
birdlife_increase_foraging_niche_tukey <- cld(glht(birdlife_increase_foraging_niche_anova, linfct=mcp(foraging_niche="Tukey")))
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
Warning in RET$pfunction("adjusted", ...) :
  Completion with error > abseps
birdlife_increase_foraging_niche_tukey
            Aquatic aerial               Aquatic dive             Aquatic ground              Aquatic perch             Aquatic plunge            Aquatic surface            Fugivore aerial 
                       "a"                        "a"                        "a"                        "a"                        "a"                        "a"                        "a" 
            Fugivore glean            Fugivore ground                 Generalist         Granivore arboreal           Granivore ground     Herbivore aquatic dive   Herbivore aquatic ground 
                       "a"                        "a"                        "a"                        "a"                        "a"                        "a"                        "a" 
 Herbivore aquatic surface         Herbivore arboreal           Herbivore ground         Invertivore aerial           Invertivore bark Invertivore glean arboreal         Invertivore ground 
                       "a"                        "a"                        "a"                        "a"                        "a"                        "a"                        "a" 
     Invertivore sally air   Invertivore sally ground  Invertivore sally surface         Nectarivore aerial          Nectarivore glean                   Omnivore           Scavenger ground 
                       "a"                        "a"                        "a"                        "a"                        "a"                        "a"                        "a" 
          Vertivore aerial   Vertivore air to surface         Vertivore arboreal           Vertivore ground            Vertivore perch 
                       "a"                        "a"                        "a"                        "a"                        "a" 
birdlife_diff_data2 <- with.tukey.label.as.group(birdlife_increase_foraging_niche_tukey, birdlife_diff_data, c("foraging_niche" = "category"))
ggplot(birdlife_diff_data2, aes(x = increase, y = foraging_niche, color = group)) + geom_boxplot() + theme_bw()

library(ggpubr)
pc_axis_figure <- function(dataset) {
  annotate_figure(
ggarrange(
  ggplot(dataset, aes(x = pc1, y = log(response), color = percentile)) + geom_point(alpha = 0.5) + geom_smooth(method = "lm", se = FALSE) + theme_bw() + rremove("ylab"),
  ggplot(dataset, aes(x = pc2, y = log(response), color = percentile)) + geom_point(alpha = 0.5) + geom_smooth(method = "lm", se = FALSE) + theme_bw() + rremove("ylab"),
  ggplot(dataset, aes(x = pc3, y = log(response), color = percentile)) + geom_point(alpha = 0.5) + geom_smooth(method = "lm", se = FALSE) + theme_bw() + rremove("ylab"),
  ggplot(dataset, aes(x = pc4, y = log(response), color = percentile)) + geom_point(alpha = 0.5) + geom_smooth(method = "lm", se = FALSE) + theme_bw() + rremove("ylab"),
  nrow = 2, ncol = 2, common.legend = T, label.x = 0),
left = text_grob("log(response)", rot = 90))
}
pc_axis_figure(merlin_species_data)
`geom_smooth()` using formula 'y ~ x'
Warning: Removed 312 rows containing non-finite values (stat_smooth).
`geom_smooth()` using formula 'y ~ x'
Warning: Removed 312 rows containing non-finite values (stat_smooth).
`geom_smooth()` using formula 'y ~ x'
Warning: Removed 312 rows containing non-finite values (stat_smooth).
`geom_smooth()` using formula 'y ~ x'
Warning: Removed 312 rows containing non-finite values (stat_smooth).
`geom_smooth()` using formula 'y ~ x'
Warning: Removed 312 rows containing non-finite values (stat_smooth).

library(lme4)
merlin_pc1_model = lmer(response ~ pc1 * percentile + (1|niche_name), data=merlin_species_data)
anova(merlin_pc1_model)
Analysis of Variance Table
               npar  Sum Sq Mean Sq F value
pc1               1 0.00042 0.00042  0.0169
percentile        1 1.50774 1.50774 59.9817
pc1:percentile    1 0.06215 0.06215  2.4724
summary(merlin_pc1_model)
Linear mixed model fit by REML ['lmerMod']
Formula: response ~ pc1 * percentile + (1 | niche_name)
   Data: merlin_species_data

REML criterion at convergence: -8.6

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-2.4461 -0.5197  0.0155  0.1840  3.3433 

Random effects:
 Groups     Name        Variance Std.Dev.
 niche_name (Intercept) 0.04729  0.2175  
 Residual               0.02514  0.1585  
Number of obs: 536, groups:  niche_name, 268

Fixed effects:
                    Estimate Std. Error t value
(Intercept)         0.117739   0.022322   5.275
pc1                -0.005011   0.006481  -0.773
percentile0.75      0.086293   0.018597   4.640
pc1:percentile0.75  0.008490   0.005399   1.572

Correlation of Fixed Effects:
            (Intr) pc1    pr0.75
pc1         -0.676              
percntl0.75 -0.417  0.282       
pc1:prc0.75  0.282 -0.417 -0.676
merlin_pc2_model = lmer(response ~ pc2 * percentile + (1|niche_name), data=merlin_species_data)
anova(merlin_pc2_model)
Analysis of Variance Table
               npar  Sum Sq Mean Sq F value
pc2               1 0.01486 0.01486  0.5864
percentile        1 1.50774 1.50774 59.5009
pc2:percentile    1 0.00812 0.00812  0.3203
summary(merlin_pc2_model)
Linear mixed model fit by REML ['lmerMod']
Formula: response ~ pc2 * percentile + (1 | niche_name)
   Data: merlin_species_data

REML criterion at convergence: -11.2

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-2.3691 -0.5150  0.0879  0.1354  3.3292 

Random effects:
 Groups     Name        Variance Std.Dev.
 niche_name (Intercept) 0.04706  0.2169  
 Residual               0.02534  0.1592  
Number of obs: 536, groups:  niche_name, 268

Fixed effects:
                    Estimate Std. Error t value
(Intercept)         0.104389   0.016836   6.200
pc2                -0.008532   0.018597  -0.459
percentile0.75      0.104347   0.014086   7.408
pc2:percentile0.75 -0.008805   0.015559  -0.566

Correlation of Fixed Effects:
            (Intr) pc2    pr0.75
pc2          0.217              
percntl0.75 -0.418 -0.091       
pc2:prc0.75 -0.091 -0.418  0.217
merlin_pc3_model = lmer(response ~ pc3 * percentile + (1|niche_name), data=merlin_species_data)
anova(merlin_pc3_model)
Analysis of Variance Table
               npar  Sum Sq Mean Sq F value
pc3               1 0.00044 0.00044  0.0187
percentile        1 1.50774 1.50774 63.7963
pc3:percentile    1 0.46195 0.46195 19.5464
summary(merlin_pc3_model)
Linear mixed model fit by REML ['lmerMod']
Formula: response ~ pc3 * percentile + (1 | niche_name)
   Data: merlin_species_data

REML criterion at convergence: -30.5

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-2.8609 -0.4057 -0.0338  0.2719  3.7473 

Random effects:
 Groups     Name        Variance Std.Dev.
 niche_name (Intercept) 0.04804  0.2192  
 Residual               0.02363  0.1537  
Number of obs: 536, groups:  niche_name, 268

Fixed effects:
                   Estimate Std. Error t value
(Intercept)         0.10758    0.01638   6.568
pc3                -0.04333    0.02594  -1.670
percentile0.75      0.10282    0.01330   7.730
pc3:percentile0.75  0.09314    0.02107   4.421

Correlation of Fixed Effects:
            (Intr) pc3    pr0.75
pc3         -0.055              
percntl0.75 -0.406  0.022       
pc3:prc0.75  0.022 -0.406 -0.055
merlin_pc4_model = lmer(response ~ pc4 * percentile + (1|niche_name), data=merlin_species_data)
anova(merlin_pc4_model)
Analysis of Variance Table
               npar  Sum Sq Mean Sq F value
pc4               1 0.06576 0.06576  2.6061
percentile        1 1.50774 1.50774 59.7558
pc4:percentile    1 0.03687 0.03687  1.4612
summary(merlin_pc4_model)
Linear mixed model fit by REML ['lmerMod']
Formula: response ~ pc4 * percentile + (1 | niche_name)
   Data: merlin_species_data

REML criterion at convergence: -17

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-2.4101 -0.5034  0.0731  0.1400  3.4938 

Random effects:
 Groups     Name        Variance Std.Dev.
 niche_name (Intercept) 0.04666  0.2160  
 Residual               0.02523  0.1588  
Number of obs: 536, groups:  niche_name, 268

Fixed effects:
                   Estimate Std. Error t value
(Intercept)         0.10678    0.01640   6.513
pc4                 0.03400    0.03543   0.960
percentile0.75      0.10683    0.01374   7.777
pc4:percentile0.75  0.03588    0.02969   1.209

Correlation of Fixed Effects:
            (Intr) pc4    pr0.75
pc4          0.046              
percntl0.75 -0.419 -0.019       
pc4:prc0.75 -0.019 -0.419  0.046
pc_axis_figure(birdlife_species_data)
`geom_smooth()` using formula 'y ~ x'
Warning: Removed 325 rows containing non-finite values (stat_smooth).
`geom_smooth()` using formula 'y ~ x'
Warning: Removed 325 rows containing non-finite values (stat_smooth).
`geom_smooth()` using formula 'y ~ x'
Warning: Removed 325 rows containing non-finite values (stat_smooth).
`geom_smooth()` using formula 'y ~ x'
Warning: Removed 325 rows containing non-finite values (stat_smooth).
`geom_smooth()` using formula 'y ~ x'
Warning: Removed 325 rows containing non-finite values (stat_smooth).

ggplot(merlin_species_data, aes(x = response, y = is_nocturnal, color = percentile)) + geom_boxplot() + theme_bw()

merlin_nocturnal_anova <- aov(response~is_nocturnal + percentile + Error(niche_name), data=merlin_species_data)
summary(merlin_nocturnal_anova)

Error: niche_name
              Df Sum Sq Mean Sq F value Pr(>F)  
is_nocturnal   1  0.462  0.4615   3.912  0.049 *
Residuals    266 31.384  0.1180                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Error: Within
            Df Sum Sq Mean Sq F value   Pr(>F)    
percentile   1  1.508  1.5077   59.65 2.29e-13 ***
Residuals  267  6.749  0.0253                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
merlin_nocturnal_anova_i <- aov(response~is_nocturnal * percentile + Error(niche_name), data=merlin_species_data)
summary(merlin_nocturnal_anova_i)

Error: niche_name
              Df Sum Sq Mean Sq F value Pr(>F)  
is_nocturnal   1  0.462  0.4615   3.912  0.049 *
Residuals    266 31.384  0.1180                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Error: Within
                         Df Sum Sq Mean Sq F value   Pr(>F)    
percentile                1  1.508  1.5077  60.685 1.51e-13 ***
is_nocturnal:percentile   1  0.140  0.1396   5.618   0.0185 *  
Residuals               266  6.609  0.0248                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
ggplot(birdlife_species_data, aes(x = response, y = is_nocturnal, color = percentile)) + geom_boxplot() + theme_bw()

birdlife_nocturnal_anova <- aov(response~is_nocturnal + percentile + Error(niche_name), data=birdlife_species_data)
summary(birdlife_nocturnal_anova)

Error: niche_name
              Df Sum Sq Mean Sq F value Pr(>F)
is_nocturnal   1   0.20  0.1982   1.658  0.199
Residuals    266  31.79  0.1195               

Error: Within
            Df Sum Sq Mean Sq F value   Pr(>F)    
percentile   1  1.327  1.3274   60.18 1.84e-13 ***
Residuals  267  5.890  0.0221                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
birdlife_nocturnal_anova_i <- aov(response~is_nocturnal * percentile + Error(niche_name), data=birdlife_species_data)
summary(birdlife_nocturnal_anova_i)

Error: niche_name
              Df Sum Sq Mean Sq F value Pr(>F)
is_nocturnal   1   0.20  0.1982   1.658  0.199
Residuals    266  31.79  0.1195               

Error: Within
                         Df Sum Sq Mean Sq F value   Pr(>F)    
percentile                1  1.327  1.3274  60.370 1.72e-13 ***
is_nocturnal:percentile   1  0.041  0.0407   1.852    0.175    
Residuals               266  5.849  0.0220                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
ggplot(merlin_species_data, aes(x = total_species, y = log(response), color = percentile)) + geom_point(alpha = 0.5) + geom_smooth(method = "lm", se = FALSE) + theme_bw()
`geom_smooth()` using formula 'y ~ x'
Warning: Removed 312 rows containing non-finite values (stat_smooth).

merlin_species_count_model = lmer(response ~ total_species * percentile + (1|niche_name), data=merlin_species_data)
anova(merlin_species_count_model)
Analysis of Variance Table
                         npar  Sum Sq Mean Sq F value
total_species               1 0.00052 0.00052  0.0206
percentile                  1 1.50774 1.50774 59.4316
total_species:percentile    1 0.00026 0.00026  0.0103
summary(merlin_species_count_model)
Linear mixed model fit by REML ['lmerMod']
Formula: response ~ total_species * percentile + (1 | niche_name)
   Data: merlin_species_data

REML criterion at convergence: 8.6

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-2.3523 -0.5462  0.1109  0.1216  3.2582 

Random effects:
 Groups     Name        Variance Std.Dev.
 niche_name (Intercept) 0.04717  0.2172  
 Residual               0.02537  0.1593  
Number of obs: 536, groups:  niche_name, 268

Fixed effects:
                               Estimate Std. Error t value
(Intercept)                   1.064e-01  1.690e-02   6.295
total_species                -1.420e-05  1.612e-04  -0.088
percentile0.75                1.064e-01  1.414e-02   7.527
total_species:percentile0.75 -1.367e-05  1.348e-04  -0.101

Correlation of Fixed Effects:
            (Intr) ttl_sp pr0.75
total_specs -0.229              
percntl0.75 -0.418  0.096       
ttl_sp:0.75  0.096 -0.418 -0.229
birdlife_species_count_model = lmer(response ~ total_species * percentile + (1|niche_name), data=birdlife_species_data)
anova(birdlife_species_count_model)
Analysis of Variance Table
                         npar Sum Sq Mean Sq F value
total_species               1 0.0000  0.0000  0.0001
percentile                  1 1.3274  1.3274 59.9531
total_species:percentile    1 0.0000  0.0000  0.0001
summary(birdlife_species_count_model)
Linear mixed model fit by REML ['lmerMod']
Formula: response ~ total_species * percentile + (1 | niche_name)
   Data: birdlife_species_data

REML criterion at convergence: -26.3

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-2.5919 -0.5189  0.0633  0.1497  3.4600 

Random effects:
 Groups     Name        Variance Std.Dev.
 niche_name (Intercept) 0.04906  0.2215  
 Residual               0.02214  0.1488  
Number of obs: 536, groups:  niche_name, 268

Fixed effects:
                              Estimate Std. Error t value
(Intercept)                  9.946e-02  1.675e-02   5.939
total_species                9.392e-07  1.597e-04   0.006
percentile0.75               9.949e-02  1.321e-02   7.534
total_species:percentile0.75 1.518e-06  1.260e-04   0.012

Correlation of Fixed Effects:
            (Intr) ttl_sp pr0.75
total_specs -0.229              
percntl0.75 -0.394  0.090       
ttl_sp:0.75  0.090 -0.394 -0.229
merlin_species_data$present <- merlin_species_data$response > 0
ggplot(merlin_species_data, aes(x = log(total_species), y = present, color = percentile)) + geom_boxplot() + theme_bw()

merlin_present_model = lmer(present ~ log(total_species) * percentile + (1|niche_name), data=merlin_species_data)
anova(merlin_present_model)
Analysis of Variance Table
                              npar Sum Sq Mean Sq  F value
log(total_species)               1 7.6804  7.6804 145.5124
percentile                       1 1.9104  1.9104  36.1952
log(total_species):percentile    1 0.0496  0.0496   0.9393
summary(merlin_present_model)
Linear mixed model fit by REML ['lmerMod']
Formula: present ~ log(total_species) * percentile + (1 | niche_name)
   Data: merlin_species_data

REML criterion at convergence: 410.7

Scaled residuals: 
     Min       1Q   Median       3Q      Max 
-2.25242 -0.44048  0.02734  0.24296  2.14911 

Random effects:
 Groups     Name        Variance Std.Dev.
 niche_name (Intercept) 0.11259  0.3356  
 Residual               0.05278  0.2297  
Number of obs: 536, groups:  niche_name, 268

Fixed effects:
                                  Estimate Std. Error t value
(Intercept)                        0.10521    0.03325   3.164
log(total_species)                 0.19281    0.01685  11.446
percentile0.75                     0.13652    0.02657   5.139
log(total_species):percentile0.75 -0.01304    0.01346  -0.969

Correlation of Fixed Effects:
            (Intr) lg(t_) pr0.75
lg(ttl_spc) -0.665              
percntl0.75 -0.399  0.266       
lg(t_):0.75  0.266 -0.399 -0.665
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQpgYGB7cn0KbGlicmFyeShzdHJpbmdyKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShiaWdycXVlcnkpCmxpYnJhcnkoTXVNSW4pCmBgYAoKYGBge3J9CnJlc3BvbnNlIDwtIHRyeShzeXN0ZW0oJ34vZ29vZ2xlLWNsb3VkLXNkay9iaW4vZ2Nsb3VkIHByb2plY3RzIGxpc3QgLS1xdWlldCcsIGludGVybiA9IFQpKQpwcm9qZWN0aWQgPC0gc3Ryc3BsaXQocmVzcG9uc2VbMl0sICIgIilbWzFdXVsxXQpgYGAKCmBgYHtyfQpvcHRpb25zKG5hLmFjdGlvbiA9ICJuYS5mYWlsIikgCmBgYAoKYGBge3J9CnNvdXJjZSgiLi9kcmVkZ2VfZnVuY3Rpb25zLlIiKQpgYGAKCmBgYHtyfQpkcmVkZ2VfYW5kX3N1YnNldCA8LSBmdW5jdGlvbihkYXRhKSB7CiAgbW9kZWwgPC0gbG0oCiAgICByZXNwb25zZSB+IGZvcmFnaW5nX25pY2hlICsgdHJvcGhpY19uaWNoZSArIGlzX25vY3R1cm5hbCArIHBjMSArIHBjMiArIHBjMyArIHBjNCArIHRvdGFsX3NwZWNpZXMsCiAgICBkYXRhPWRhdGEKICApCiAgZHJlZGdlX3Jlc3VsdCA8LSBkcmVkZ2UobW9kZWwpCiAgc3VtbWFyeShtb2RlbC5hdmcoZHJlZGdlX3Jlc3VsdCwgc3Vic2V0ID0gZGVsdGEgPCAxMCkpCn0KYGBgCgpgYGB7cn0KbG9hZF9uaWNoZV9kYXRhIDwtIGZ1bmN0aW9uKCkgewogIGZpbGVuYW1lIDwtICdzcGVjaWVzX2FuYWx5c2lzX2NhY2hlLmNzdicKICAKICBpZiAoIWZpbGUuZXhpc3RzKGZpbGVuYW1lKSkgewogICAgCiAgICBzcWwgPC0gIgogICAgICAgIFNFTEVDVCAKICAgICAgICAgIG5pY2hlX25hbWUsCiAgICAgICAgICBmb3JhZ2luZ19uaWNoZSwgCiAgICAgICAgICB0cm9waGljX25pY2hlLCAKICAgICAgICAgIGlzX25vY3R1cmFsLCAKICAgICAgICAgIHRvdGFsX3NwZWNpZXMsCiAgICAgICAgICBtZXJsaW5fMTBfcGVyY19yYXRpbywgCiAgICAgICAgICBtZXJsaW5fMjBfcGVyY19yYXRpbywgCiAgICAgICAgICBiaXJkbGlmZV8xMF9wZXJjX3JhdGlvLCAKICAgICAgICAgIGJpcmRsaWZlXzIwX3BlcmNfcmF0aW8sIAogICAgICAgICAgZWl0aGVyXzEwX3BlcmNfcmF0aW8sIAogICAgICAgICAgZWl0aGVyXzIwX3BlcmNfcmF0aW8sIAogICAgICAgICAgYm90aF8xMF9wZXJjX3JhdGlvLCAKICAgICAgICAgIGJvdGhfMjBfcGVyY19yYXRpbywgCiAgICAgICAgICBib2R5X21vcnBoc3BhY2UucGMxLm1lYW4gQVMgcGMxLCAKICAgICAgICAgIGJvZHlfbW9ycGhzcGFjZS5wYzIubWVhbiBBUyBwYzIsIAogICAgICAgICAgYm9keV9tb3JwaHNwYWNlLnBjMy5tZWFuIEFTIHBjMywgCiAgICAgICAgICBib2R5X21vcnBoc3BhY2UucGM0Lm1lYW4gQVMgcGM0CiAgICAgICAgRlJPTSBgZW5kbGVzcy1tYXR0ZXItMjk3MjE0Lm1vZGVsMi5uaWNoZV9hbmFseXNpc19tb2RlbGAgTElNSVQgMTAwMCAKICAgICIKICAKICAgIHRiIDwtIGJxX3Byb2plY3RfcXVlcnkocHJvamVjdGlkLCBzcWwpCgogICAgZGF0YSA8LSBicV90YWJsZV9kb3dubG9hZCh0YikKICAgIHdyaXRlX2NzdihkYXRhLCBmaWxlbmFtZSkKICB9CiAgCiAgZGF0YSA8LSByZWFkX2NzdihmaWxlbmFtZSkKICAKICBkYXRhW2lzLm5hKGRhdGEkZm9yYWdpbmdfbmljaGUpLF0kZm9yYWdpbmdfbmljaGUgPC0gJ09tbml2b3JlJwogIAogIGRhdGEkZm9yYWdpbmdfbmljaGUgPSBhcy5mYWN0b3IoZGF0YSRmb3JhZ2luZ19uaWNoZSkKICBkYXRhJHRyb3BoaWNfbmljaGUgPSBhcy5mYWN0b3IoZGF0YSR0cm9waGljX25pY2hlKQogIGRhdGEkaXNfbm9jdHVybmFsID0gYXMuZmFjdG9yKGRhdGEkaXNfbm9jdHVyYWwpCiAgCiAgZGF0YQp9CgpkYXRhX2Zvcl9yZXNwb25zZSA8LSBmdW5jdGlvbihjb2x1bW5fbmFtZV9mb3JfcmVzcG9uc2UpIHsKICBkYXRhIDwtIGxvYWRfbmljaGVfZGF0YSgpCiAgbmFtZXMoZGF0YSlbbmFtZXMoZGF0YSkgPT0gY29sdW1uX25hbWVfZm9yX3Jlc3BvbnNlXSA8LSAicmVzcG9uc2UiCiAgCiAgZGF0YVssYygibmljaGVfbmFtZSIsICJyZXNwb25zZSIsICJmb3JhZ2luZ19uaWNoZSIsICJ0cm9waGljX25pY2hlIiwgImlzX25vY3R1cm5hbCIsICJwYzEiLCAicGMyIiwgInBjMyIsICJwYzQiLCAidG90YWxfc3BlY2llcyIpXQp9CmBgYAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCjAuMjUgUGVyY2VudGlsZSAtIDEwJSBvZiBzcGVjaWVzCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKYGBge3J9Cm1lcmxpbl8xMF9kYXRhIDwtIGRhdGFfZm9yX3Jlc3BvbnNlKCdtZXJsaW5fMTBfcGVyY19yYXRpbycpCm1lcmxpbl8xMF9kYXRhCmBgYAoKCmBgYHtyfQptZXJsaW5fMTBfcmVzdWx0IDwtIGRyZWRnZV9hbmRfc3Vic2V0KG1lcmxpbl8xMF9kYXRhKQptZXJsaW5fMTBfc3VtbSA8LSBtb2RlbF9zdW1tYXJ5KCdtZXJsaW5fMTAnLCAnc3BlY2llcycsIG1lcmxpbl8xMF9yZXN1bHQpCm1lcmxpbl8xMF9zdW1tCmBgYAoKYGBge3J9CmJpcmRsaWZlXzEwX2RhdGEgPC0gZGF0YV9mb3JfcmVzcG9uc2UoJ2JpcmRsaWZlXzEwX3BlcmNfcmF0aW8nKQpiaXJkbGlmZV8xMF9yZXN1bHQgPC0gZHJlZGdlX2FuZF9zdWJzZXQoYmlyZGxpZmVfMTBfZGF0YSkKYmlyZGxpZmVfMTBfc3VtbSA8LSBtb2RlbF9zdW1tYXJ5KCdiaXJkbGlmZV8xMCcsICdzcGVjaWVzJywgYmlyZGxpZmVfMTBfcmVzdWx0KQpiaXJkbGlmZV8xMF9zdW1tCmBgYAoKCmBgYHtyfQpib3RoXzEwX2RhdGEgPC0gZGF0YV9mb3JfcmVzcG9uc2UoJ2JvdGhfMTBfcGVyY19yYXRpbycpCmJvdGhfMTBfcmVzdWx0IDwtIGRyZWRnZV9hbmRfc3Vic2V0KGJvdGhfMTBfZGF0YSkKYm90aF8xMF9zdW1tIDwtIG1vZGVsX3N1bW1hcnkoJ2JvdGhfMTAnLCAnc3BlY2llcycsIGJvdGhfMTBfcmVzdWx0KQpib3RoXzEwX3N1bW0KYGBgCgoKYGBge3J9CmVpdGhlcl8xMF9kYXRhIDwtIGRhdGFfZm9yX3Jlc3BvbnNlKCdlaXRoZXJfMTBfcGVyY19yYXRpbycpCmVpdGhlcl8xMF9yZXN1bHQgPC0gZHJlZGdlX2FuZF9zdWJzZXQoZWl0aGVyXzEwX2RhdGEpCmVpdGhlcl8xMF9zdW1tIDwtIG1vZGVsX3N1bW1hcnkoJ2VpdGhlcl8xMCcsICdzcGVjaWVzJywgZWl0aGVyXzEwX3Jlc3VsdCkKZWl0aGVyXzEwX3N1bW0KYGBgCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KRnVsbCByZXN1bHQgZm9yIDEwJSBvZiBzcGVjaWVzCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpgYGB7cn0KYWxsX3NwZWNpZXNfcmVzdWx0cyA8LSBmdWxsX2pvaW4oZnVsbF9qb2luKG1lcmxpbl8xMF9zdW1tLCBiaXJkbGlmZV8xMF9zdW1tKSwgZnVsbF9qb2luKGJvdGhfMTBfc3VtbSwgZWl0aGVyXzEwX3N1bW0pKQp3cml0ZV9jc3YoYWxsX3NwZWNpZXNfcmVzdWx0cywgInNwZWNpZXNfYW5hbHlzaXNfcmVzdWx0XzEwX3BlcmMuY3N2IikKYGBgCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KMC43NSBQZXJjZW50aWxlIC0gMjAlIG9mIHNwZWNpZXMKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpgYGB7cn0KbWVybGluXzIwX2RhdGEgPC0gZGF0YV9mb3JfcmVzcG9uc2UoJ21lcmxpbl8yMF9wZXJjX3JhdGlvJykKbWVybGluXzIwX3Jlc3VsdCA8LSBkcmVkZ2VfYW5kX3N1YnNldChtZXJsaW5fMjBfZGF0YSkKbWVybGluXzIwX3N1bW0gPC0gbW9kZWxfc3VtbWFyeSgnbWVybGluXzIwJywgJ3NwZWNpZXMnLCBtZXJsaW5fMjBfcmVzdWx0KQptZXJsaW5fMjBfc3VtbQpgYGAKCmBgYHtyfQpiaXJkbGlmZV8yMF9kYXRhIDwtIGRhdGFfZm9yX3Jlc3BvbnNlKCdiaXJkbGlmZV8yMF9wZXJjX3JhdGlvJykKYmlyZGxpZmVfMjBfcmVzdWx0IDwtIGRyZWRnZV9hbmRfc3Vic2V0KGJpcmRsaWZlXzIwX2RhdGEpCmJpcmRsaWZlXzIwX3N1bW0gPC0gbW9kZWxfc3VtbWFyeSgnYmlyZGxpZmVfMjAnLCAnc3BlY2llcycsIGJpcmRsaWZlXzIwX3Jlc3VsdCkKYmlyZGxpZmVfMjBfc3VtbQpgYGAKCmBgYHtyfQpib3RoXzIwX2RhdGEgPC0gZGF0YV9mb3JfcmVzcG9uc2UoJ2JvdGhfMjBfcGVyY19yYXRpbycpCmJvdGhfMjBfcmVzdWx0IDwtIGRyZWRnZV9hbmRfc3Vic2V0KGJvdGhfMjBfZGF0YSkKYm90aF8yMF9zdW1tIDwtIG1vZGVsX3N1bW1hcnkoJ2JvdGhfMjAnLCAnc3BlY2llcycsIGJvdGhfMjBfcmVzdWx0KQpib3RoXzIwX3N1bW0KYGBgCgpgYGB7cn0KZWl0aGVyXzIwX2RhdGEgPC0gZGF0YV9mb3JfcmVzcG9uc2UoJ2VpdGhlcl8yMF9wZXJjX3JhdGlvJykKZWl0aGVyXzIwX3Jlc3VsdCA8LSBkcmVkZ2VfYW5kX3N1YnNldChlaXRoZXJfMjBfZGF0YSkKZWl0aGVyXzIwX3N1bW0gPC0gbW9kZWxfc3VtbWFyeSgnZWl0aGVyXzIwJywgJ3NwZWNpZXMnLCBlaXRoZXJfMjBfcmVzdWx0KQplaXRoZXJfMjBfc3VtbQpgYGAKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpGdWxsIHJlc3VsdCBmb3IgMTAlIG9mIHNwZWNpZXMKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmBgYHtyfQphbGxfc3BlY2llc19yZXN1bHRzIDwtIGZ1bGxfam9pbihmdWxsX2pvaW4obWVybGluXzIwX3N1bW0sIGJpcmRsaWZlXzIwX3N1bW0pLCBmdWxsX2pvaW4oYm90aF8yMF9zdW1tLCBlaXRoZXJfMjBfc3VtbSkpCndyaXRlX2NzdihhbGxfc3BlY2llc19yZXN1bHRzLCAic3BlY2llc19hbmFseXNpc19yZXN1bHRfMjBfcGVyYy5jc3YiKQpgYGAKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpDb21wYXJpbmcgdGhlIDIgcGVyY2VudGlsZXMKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpgYGB7cn0KZ2dwbG90KG1lcmxpbl8xMF9kYXRhLCBhZXMoeCA9IHJlc3BvbnNlKSkgKyBnZW9tX2Jhcih3aWR0aCA9IDAuMSkKYGBgCgpgYGB7cn0KYmluZF9zZXRzIDwtIGZ1bmN0aW9uKGZpcnN0X3BlcmNlbnRpbGUsIHNlY29uZF9wZXJjZW50aWxlKSB7CiAgZmlyc3RfcGVyY2VudGlsZSRwZXJjZW50aWxlIDwtICIwLjI1IgogIHNlY29uZF9wZXJjZW50aWxlJHBlcmNlbnRpbGUgPC0gIjAuNzUiCiAgcmJpbmQoZmlyc3RfcGVyY2VudGlsZSwgc2Vjb25kX3BlcmNlbnRpbGUpCn0KCm1lcmxpbl9zcGVjaWVzX2RhdGEgPC0gYmluZF9zZXRzKG1lcmxpbl8xMF9kYXRhLCAgbWVybGluXzIwX2RhdGEpCmJpcmRsaWZlX3NwZWNpZXNfZGF0YSA8LSBiaW5kX3NldHMoYmlyZGxpZmVfMTBfZGF0YSwgIGJpcmRsaWZlXzIwX2RhdGEpCmVpdGhlcl9zcGVjaWVzX2RhdGEgPC0gYmluZF9zZXRzKGVpdGhlcl8xMF9kYXRhLCAgZWl0aGVyXzIwX2RhdGEpCmJvdGhfc3BlY2llc19kYXRhIDwtIGJpbmRfc2V0cyhib3RoXzEwX2RhdGEsICBib3RoXzIwX2RhdGEpCmBgYAoKYGBge3J9CmRpZmZfc2V0IDwtIGZ1bmN0aW9uKGZpcnN0X3BlcmNlbnRpbGUsIHNlY29uZF9wZXJjZW50aWxlKSB7CiAgc2Vjb25kX3BlcmNlbnRpbGUkcmVzcG9uc2VfMjAgPC0gc2Vjb25kX3BlcmNlbnRpbGUkcmVzcG9uc2UKICAKICByZXN1bHQgPC0gcmlnaHRfam9pbihmaXJzdF9wZXJjZW50aWxlLCBzZWNvbmRfcGVyY2VudGlsZVssYygibmljaGVfbmFtZSIsICJyZXNwb25zZV8yMCIpXSwgYnkgPSBjKCJuaWNoZV9uYW1lIikpCiAgcmVzdWx0JGRpZmYgPC0gcmVzdWx0JHJlc3BvbnNlXzIwIC0gcmVzdWx0JHJlc3BvbnNlCiAgcmVzdWx0JGluY3JlYXNlIDwtIHJlc3VsdCRkaWZmIC8gcmVzdWx0JHJlc3BvbnNlXzIwCiAgcmVzdWx0JGluY3JlYXNlW2lzLm5hKHJlc3VsdCRpbmNyZWFzZSldID0gMAogIHJlc3VsdCRyZXNwb25zZV8xMCA8LSByZXN1bHQkcmVzcG9uc2UKICByZXN1bHRbLGMoInJlc3BvbnNlXzEwIiwgInJlc3BvbnNlXzIwIiwgImRpZmYiLCAiaW5jcmVhc2UiLCAiZm9yYWdpbmdfbmljaGUiLCAidHJvcGhpY19uaWNoZSIsICJpc19ub2N0dXJuYWwiLCAicGMxIiwgInBjMiIsICJwYzMiLCAicGM0IiwgInRvdGFsX3NwZWNpZXMiKV0KfQoKbWVybGluX2RpZmZfZGF0YSA8LSBkaWZmX3NldChtZXJsaW5fMTBfZGF0YSwgIG1lcmxpbl8yMF9kYXRhKQpiaXJkbGlmZV9kaWZmX2RhdGEgPC0gZGlmZl9zZXQoYmlyZGxpZmVfMTBfZGF0YSwgIGJpcmRsaWZlXzIwX2RhdGEpCmVpdGhlcl9kaWZmX2RhdGEgPC0gZGlmZl9zZXQoZWl0aGVyXzEwX2RhdGEsICBlaXRoZXJfMjBfZGF0YSkKYm90aF9kaWZmX2RhdGEgPC0gZGlmZl9zZXQoYm90aF8xMF9kYXRhLCAgYm90aF8yMF9kYXRhKQoKbWVybGluX2RpZmZfZGF0YQpgYGAKCmBgYHtyfQpnZ3Bsb3QobWVybGluX3NwZWNpZXNfZGF0YSwgYWVzKHggPSByZXNwb25zZSwgeSA9IHRyb3BoaWNfbmljaGUsIGNvbG9yID0gcGVyY2VudGlsZSkpICsgZ2VvbV9ib3hwbG90KCkgKyB0aGVtZV9idygpCmBgYAoKYGBge3J9Cm1lcmxpbl90cm9waGljX25pY2hlX25pY2hlX2Fub3ZhIDwtIGFvdihyZXNwb25zZX50cm9waGljX25pY2hlICsgcGVyY2VudGlsZSArIEVycm9yKG5pY2hlX25hbWUpLCBkYXRhPW1lcmxpbl9zcGVjaWVzX2RhdGEpCnN1bW1hcnkobWVybGluX3Ryb3BoaWNfbmljaGVfbmljaGVfYW5vdmEpCgptZXJsaW5fdHJvcGhpY19uaWNoZV9uaWNoZV9hbm92YV9pIDwtIGFvdihyZXNwb25zZX50cm9waGljX25pY2hlICogcGVyY2VudGlsZSArIEVycm9yKG5pY2hlX25hbWUpLCBkYXRhPW1lcmxpbl9zcGVjaWVzX2RhdGEpCnN1bW1hcnkobWVybGluX3Ryb3BoaWNfbmljaGVfbmljaGVfYW5vdmFfaSkKYGBgCgpgYGB7cn0KcGFpcndpc2Uud2lsY294LnRlc3QobWVybGluX2RpZmZfZGF0YSRpbmNyZWFzZSwgbWVybGluX2RpZmZfZGF0YSR0cm9waGljX25pY2hlKQpgYGAKYGBge3J9CmxpYnJhcnkobXVsdGNvbXApCm1lcmxpbl9pbmNyZWFzZV90cm9waWNfbmljaGVfYW5vdmEgPC1hb3YoaW5jcmVhc2V+dHJvcGhpY19uaWNoZSwgZGF0YT1tZXJsaW5fZGlmZl9kYXRhKQpzdW1tYXJ5KG1lcmxpbl9pbmNyZWFzZV90cm9waWNfbmljaGVfYW5vdmEpCgptZXJsaW5faW5jcmVhc2VfdHJvcGljX25pY2hlX3R1a2V5IDwtIGNsZChnbGh0KG1lcmxpbl9pbmNyZWFzZV90cm9waWNfbmljaGVfYW5vdmEsIGxpbmZjdD1tY3AodHJvcGhpY19uaWNoZT0iVHVrZXkiKSkpCgptZXJsaW5faW5jcmVhc2VfdHJvcGljX25pY2hlX3R1a2V5CmBgYAoKYGBge3J9CnBsb3QobWVybGluX2luY3JlYXNlX3Ryb3BpY19uaWNoZV90dWtleSkKYGBgCmBgYHtyfQp3aXRoLnR1a2V5LmxhYmVsLmFzLmdyb3VwIDwtIGZ1bmN0aW9uKHR1a2V5LCBkYXRhc2V0LCBqb2luX2J5KSB7CiAgbGFiZWxzIDwtIGRhdGEuZnJhbWUodHVrZXkkbWNsZXR0ZXJzJExldHRlcnMpCiAgbGFiZWxzJGNhdGVnb3J5IDwtIHJvd25hbWVzKGxhYmVscykKICBjb2xuYW1lcyhsYWJlbHMpIDwtIGMoImdyb3VwIiwgImNhdGVnb3J5IikKICAKICAKICBsZWZ0X2pvaW4oZGF0YXNldCwgbGFiZWxzLCBieSA9IGpvaW5fYnkpCn0KYGBgCgpgYGB7cn0KbWVybGluX2RpZmZfZGF0YTEgPC0gd2l0aC50dWtleS5sYWJlbC5hcy5ncm91cChtZXJsaW5faW5jcmVhc2VfdHJvcGljX25pY2hlX3R1a2V5LCBtZXJsaW5fZGlmZl9kYXRhLCBjKCJ0cm9waGljX25pY2hlIiA9ICJjYXRlZ29yeSIpKQptZXJsaW5fZGlmZl9kYXRhMQpgYGAKCmBgYHtyfQpnZ3Bsb3QobWVybGluX2RpZmZfZGF0YTEsIGFlcyh4ID0gaW5jcmVhc2UsIHkgPSB0cm9waGljX25pY2hlLCBjb2xvciA9IGdyb3VwKSkgKyBnZW9tX2JveHBsb3QoKSArIHRoZW1lX2J3KCkKYGBgCgpgYGB7cn0KZ2dwbG90KGJpcmRsaWZlX3NwZWNpZXNfZGF0YSwgYWVzKHggPSByZXNwb25zZSwgeSA9IHRyb3BoaWNfbmljaGUsIGNvbG9yID0gcGVyY2VudGlsZSkpICsgZ2VvbV9ib3hwbG90KCkgKyB0aGVtZV9idygpCmBgYAoKYGBge3J9CmJpcmRsaWZlX3Ryb3BoaWNfbmljaGVfbmljaGVfYW5vdmEgPC0gYW92KHJlc3BvbnNlfnRyb3BoaWNfbmljaGUgKyBwZXJjZW50aWxlICsgRXJyb3IobmljaGVfbmFtZSksIGRhdGE9YmlyZGxpZmVfc3BlY2llc19kYXRhKQpzdW1tYXJ5KGJpcmRsaWZlX3Ryb3BoaWNfbmljaGVfbmljaGVfYW5vdmEpCgpiaXJkbGlmZV90cm9waGljX25pY2hlX25pY2hlX2Fub3ZhX2kgPC0gYW92KHJlc3BvbnNlfnRyb3BoaWNfbmljaGUgKiBwZXJjZW50aWxlICsgRXJyb3IobmljaGVfbmFtZSksIGRhdGE9YmlyZGxpZmVfc3BlY2llc19kYXRhKQpzdW1tYXJ5KGJpcmRsaWZlX3Ryb3BoaWNfbmljaGVfbmljaGVfYW5vdmFfaSkKYGBgCgpgYGB7cn0KYmlyZGxpZmVfaW5jcmVhc2VfdHJvcGljX25pY2hlX2Fub3ZhIDwtYW92KGluY3JlYXNlfnRyb3BoaWNfbmljaGUsIGRhdGE9YmlyZGxpZmVfZGlmZl9kYXRhKQpzdW1tYXJ5KGJpcmRsaWZlX2luY3JlYXNlX3Ryb3BpY19uaWNoZV9hbm92YSkKCmJpcmRsaWZlX2luY3JlYXNlX3Ryb3BpY19uaWNoZV90dWtleSA8LSBjbGQoZ2xodChiaXJkbGlmZV9pbmNyZWFzZV90cm9waWNfbmljaGVfYW5vdmEsIGxpbmZjdD1tY3AodHJvcGhpY19uaWNoZT0iVHVrZXkiKSkpCgpiaXJkbGlmZV9pbmNyZWFzZV90cm9waWNfbmljaGVfdHVrZXkKYGBgCgpgYGB7cn0KYmlyZGxpZmVfZGlmZl9kYXRhMSA8LSB3aXRoLnR1a2V5LmxhYmVsLmFzLmdyb3VwKGJpcmRsaWZlX2luY3JlYXNlX3Ryb3BpY19uaWNoZV90dWtleSwgYmlyZGxpZmVfZGlmZl9kYXRhLCBjKCJ0cm9waGljX25pY2hlIiA9ICJjYXRlZ29yeSIpKQpnZ3Bsb3QoYmlyZGxpZmVfZGlmZl9kYXRhMSwgYWVzKHggPSBpbmNyZWFzZSwgeSA9IHRyb3BoaWNfbmljaGUsIGNvbG9yID0gZ3JvdXApKSArIGdlb21fYm94cGxvdCgpICsgdGhlbWVfYncoKQpgYGAKCmBgYHtyfQpnZ3Bsb3QoZWl0aGVyX3NwZWNpZXNfZGF0YSwgYWVzKHggPSByZXNwb25zZSwgeSA9IHRyb3BoaWNfbmljaGUsIGNvbG9yID0gcGVyY2VudGlsZSkpICsgZ2VvbV9ib3hwbG90KCkgKyB0aGVtZV9idygpCmBgYAoKYGBge3J9CmdncGxvdChib3RoX3NwZWNpZXNfZGF0YSwgYWVzKHggPSByZXNwb25zZSwgeSA9IHRyb3BoaWNfbmljaGUsIGNvbG9yID0gcGVyY2VudGlsZSkpICsgZ2VvbV9ib3hwbG90KCkgKyB0aGVtZV9idygpCmBgYAoKYGBge3J9Cm5yb3cobWVybGluXzEwX2RhdGFbbWVybGluXzEwX2RhdGEkcmVzcG9uc2UgPiAwLF0pCm5yb3cobWVybGluXzIwX2RhdGFbbWVybGluXzIwX2RhdGEkcmVzcG9uc2UgPiAwLF0pCmBgYAoKYGBge3J9Cm5yb3coYmlyZGxpZmVfMTBfZGF0YVtiaXJkbGlmZV8xMF9kYXRhJHJlc3BvbnNlID4gMCxdKQpucm93KGJpcmRsaWZlXzIwX2RhdGFbYmlyZGxpZmVfMjBfZGF0YSRyZXNwb25zZSA+IDAsXSkKYGBgCgpgYGB7cn0KbnJvdyhlaXRoZXJfMTBfZGF0YVtlaXRoZXJfMTBfZGF0YSRyZXNwb25zZSA+IDAsXSkKbnJvdyhlaXRoZXJfMjBfZGF0YVtlaXRoZXJfMjBfZGF0YSRyZXNwb25zZSA+IDAsXSkKYGBgCgpgYGB7cn0KbnJvdyhib3RoXzEwX2RhdGFbYm90aF8xMF9kYXRhJHJlc3BvbnNlID4gMCxdKQpucm93KGJvdGhfMjBfZGF0YVtib3RoXzIwX2RhdGEkcmVzcG9uc2UgPiAwLF0pCmBgYAoKYGBge3J9CmdncGxvdChtZXJsaW5fc3BlY2llc19kYXRhLCBhZXMoeCA9IHJlc3BvbnNlLCB5ID0gZm9yYWdpbmdfbmljaGUsIGNvbG9yID0gcGVyY2VudGlsZSkpICsgZ2VvbV9ib3hwbG90KCkgKyB0aGVtZV9idygpCmBgYAoKYGBge3J9CmludGVyYWN0aW9uLnBsb3QobWVybGluX3NwZWNpZXNfZGF0YSRmb3JhZ2luZ19uaWNoZSwgbWVybGluX3NwZWNpZXNfZGF0YSRwZXJjZW50aWxlLCBtZXJsaW5fc3BlY2llc19kYXRhJHJlc3BvbnNlKQpgYGAKCmBgYHtyfQptZXJsaW5fZm9yYWdpbmdfbmljaGVfYW5vdmEgPC0gYW92KHJlc3BvbnNlfmZvcmFnaW5nX25pY2hlICsgcGVyY2VudGlsZSArIEVycm9yKG5pY2hlX25hbWUpLCBkYXRhPW1lcmxpbl9zcGVjaWVzX2RhdGEpCnN1bW1hcnkobWVybGluX2ZvcmFnaW5nX25pY2hlX2Fub3ZhKQoKbWVybGluX2ZvcmFnaW5nX25pY2hlX2Fub3ZhX2kgPC0gYW92KHJlc3BvbnNlfmZvcmFnaW5nX25pY2hlICogcGVyY2VudGlsZSArIEVycm9yKG5pY2hlX25hbWUpLCBkYXRhPW1lcmxpbl9zcGVjaWVzX2RhdGEpCnN1bW1hcnkobWVybGluX2ZvcmFnaW5nX25pY2hlX2Fub3ZhX2kpCmBgYAoKYGBge3J9Cm1lcmxpbl9pbmNyZWFzZV9mb3JhZ2luZ19uaWNoZV9hbm92YSA8LWFvdihpbmNyZWFzZX5mb3JhZ2luZ19uaWNoZSwgZGF0YT1tZXJsaW5fZGlmZl9kYXRhKQpzdW1tYXJ5KG1lcmxpbl9pbmNyZWFzZV9mb3JhZ2luZ19uaWNoZV9hbm92YSkKCm1lcmxpbl9pbmNyZWFzZV9mb3JhZ2luZ19uaWNoZV90dWtleSA8LSBjbGQoZ2xodChtZXJsaW5faW5jcmVhc2VfZm9yYWdpbmdfbmljaGVfYW5vdmEsIGxpbmZjdD1tY3AoZm9yYWdpbmdfbmljaGU9IlR1a2V5IikpKQoKbWVybGluX2luY3JlYXNlX2ZvcmFnaW5nX25pY2hlX3R1a2V5CmBgYAoKYGBge3J9Cm1lcmxpbl9kaWZmX2RhdGEyIDwtIHdpdGgudHVrZXkubGFiZWwuYXMuZ3JvdXAobWVybGluX2luY3JlYXNlX2ZvcmFnaW5nX25pY2hlX3R1a2V5LCBtZXJsaW5fZGlmZl9kYXRhLCBjKCJmb3JhZ2luZ19uaWNoZSIgPSAiY2F0ZWdvcnkiKSkKZ2dwbG90KG1lcmxpbl9kaWZmX2RhdGEyLCBhZXMoeCA9IGluY3JlYXNlLCB5ID0gZm9yYWdpbmdfbmljaGUsIGNvbG9yID0gZ3JvdXApKSArIGdlb21fYm94cGxvdCgpICsgdGhlbWVfYncoKQpgYGAKCgpgYGB7cn0KZ2dwbG90KGJpcmRsaWZlX3NwZWNpZXNfZGF0YSwgYWVzKHggPSByZXNwb25zZSwgeSA9IGZvcmFnaW5nX25pY2hlLCBjb2xvciA9IHBlcmNlbnRpbGUpKSArIGdlb21fYm94cGxvdCgpICsgdGhlbWVfYncoKQpgYGAKCmBgYHtyfQpiaXJkbGlmZV9mb3JhZ2luZ19uaWNoZV9hbm92YSA8LSBhb3YocmVzcG9uc2V+Zm9yYWdpbmdfbmljaGUgKyBwZXJjZW50aWxlICsgRXJyb3IobmljaGVfbmFtZSksIGRhdGE9YmlyZGxpZmVfc3BlY2llc19kYXRhKQpzdW1tYXJ5KGJpcmRsaWZlX2ZvcmFnaW5nX25pY2hlX2Fub3ZhKQoKYmlyZGxpZmVfZm9yYWdpbmdfbmljaGVfYW5vdmFfaSA8LSBhb3YocmVzcG9uc2V+Zm9yYWdpbmdfbmljaGUgKiBwZXJjZW50aWxlICsgRXJyb3IobmljaGVfbmFtZSksIGRhdGE9YmlyZGxpZmVfc3BlY2llc19kYXRhKQpzdW1tYXJ5KGJpcmRsaWZlX2ZvcmFnaW5nX25pY2hlX2Fub3ZhX2kpCmBgYAoKYGBge3J9CmJpcmRsaWZlX2luY3JlYXNlX2ZvcmFnaW5nX25pY2hlX2Fub3ZhIDwtYW92KGluY3JlYXNlfmZvcmFnaW5nX25pY2hlLCBkYXRhPWJpcmRsaWZlX2RpZmZfZGF0YSkKc3VtbWFyeShiaXJkbGlmZV9pbmNyZWFzZV9mb3JhZ2luZ19uaWNoZV9hbm92YSkKCmJpcmRsaWZlX2luY3JlYXNlX2ZvcmFnaW5nX25pY2hlX3R1a2V5IDwtIGNsZChnbGh0KGJpcmRsaWZlX2luY3JlYXNlX2ZvcmFnaW5nX25pY2hlX2Fub3ZhLCBsaW5mY3Q9bWNwKGZvcmFnaW5nX25pY2hlPSJUdWtleSIpKSkKCmJpcmRsaWZlX2luY3JlYXNlX2ZvcmFnaW5nX25pY2hlX3R1a2V5CmBgYAoKYGBge3J9CmJpcmRsaWZlX2RpZmZfZGF0YTIgPC0gd2l0aC50dWtleS5sYWJlbC5hcy5ncm91cChiaXJkbGlmZV9pbmNyZWFzZV9mb3JhZ2luZ19uaWNoZV90dWtleSwgYmlyZGxpZmVfZGlmZl9kYXRhLCBjKCJmb3JhZ2luZ19uaWNoZSIgPSAiY2F0ZWdvcnkiKSkKZ2dwbG90KGJpcmRsaWZlX2RpZmZfZGF0YTIsIGFlcyh4ID0gaW5jcmVhc2UsIHkgPSBmb3JhZ2luZ19uaWNoZSwgY29sb3IgPSBncm91cCkpICsgZ2VvbV9ib3hwbG90KCkgKyB0aGVtZV9idygpCmBgYAoKYGBge3J9CmxpYnJhcnkoZ2dwdWJyKQpgYGAKCmBgYHtyfQpwY19heGlzX2ZpZ3VyZSA8LSBmdW5jdGlvbihkYXRhc2V0KSB7CiAgYW5ub3RhdGVfZmlndXJlKApnZ2FycmFuZ2UoCiAgZ2dwbG90KGRhdGFzZXQsIGFlcyh4ID0gcGMxLCB5ID0gbG9nKHJlc3BvbnNlKSwgY29sb3IgPSBwZXJjZW50aWxlKSkgKyBnZW9tX3BvaW50KGFscGhhID0gMC41KSArIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRkFMU0UpICsgdGhlbWVfYncoKSArIHJyZW1vdmUoInlsYWIiKSwKICBnZ3Bsb3QoZGF0YXNldCwgYWVzKHggPSBwYzIsIHkgPSBsb2cocmVzcG9uc2UpLCBjb2xvciA9IHBlcmNlbnRpbGUpKSArIGdlb21fcG9pbnQoYWxwaGEgPSAwLjUpICsgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGQUxTRSkgKyB0aGVtZV9idygpICsgcnJlbW92ZSgieWxhYiIpLAogIGdncGxvdChkYXRhc2V0LCBhZXMoeCA9IHBjMywgeSA9IGxvZyhyZXNwb25zZSksIGNvbG9yID0gcGVyY2VudGlsZSkpICsgZ2VvbV9wb2ludChhbHBoYSA9IDAuNSkgKyBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEZBTFNFKSArIHRoZW1lX2J3KCkgKyBycmVtb3ZlKCJ5bGFiIiksCiAgZ2dwbG90KGRhdGFzZXQsIGFlcyh4ID0gcGM0LCB5ID0gbG9nKHJlc3BvbnNlKSwgY29sb3IgPSBwZXJjZW50aWxlKSkgKyBnZW9tX3BvaW50KGFscGhhID0gMC41KSArIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRkFMU0UpICsgdGhlbWVfYncoKSArIHJyZW1vdmUoInlsYWIiKSwKICBucm93ID0gMiwgbmNvbCA9IDIsIGNvbW1vbi5sZWdlbmQgPSBULCBsYWJlbC54ID0gMCksCmxlZnQgPSB0ZXh0X2dyb2IoImxvZyhyZXNwb25zZSkiLCByb3QgPSA5MCkpCn0KYGBgCgpgYGB7cn0KcGNfYXhpc19maWd1cmUobWVybGluX3NwZWNpZXNfZGF0YSkKYGBgCgpgYGB7cn0KbGlicmFyeShsbWU0KQptZXJsaW5fcGMxX21vZGVsID0gbG1lcihyZXNwb25zZSB+IHBjMSAqIHBlcmNlbnRpbGUgKyAoMXxuaWNoZV9uYW1lKSwgZGF0YT1tZXJsaW5fc3BlY2llc19kYXRhKQphbm92YShtZXJsaW5fcGMxX21vZGVsKQpzdW1tYXJ5KG1lcmxpbl9wYzFfbW9kZWwpCmBgYAoKYGBge3J9Cm1lcmxpbl9wYzJfbW9kZWwgPSBsbWVyKHJlc3BvbnNlIH4gcGMyICogcGVyY2VudGlsZSArICgxfG5pY2hlX25hbWUpLCBkYXRhPW1lcmxpbl9zcGVjaWVzX2RhdGEpCmFub3ZhKG1lcmxpbl9wYzJfbW9kZWwpCnN1bW1hcnkobWVybGluX3BjMl9tb2RlbCkKYGBgCgpgYGB7cn0KbWVybGluX3BjM19tb2RlbCA9IGxtZXIocmVzcG9uc2UgfiBwYzMgKiBwZXJjZW50aWxlICsgKDF8bmljaGVfbmFtZSksIGRhdGE9bWVybGluX3NwZWNpZXNfZGF0YSkKYW5vdmEobWVybGluX3BjM19tb2RlbCkKc3VtbWFyeShtZXJsaW5fcGMzX21vZGVsKQpgYGAKCmBgYHtyfQptZXJsaW5fcGM0X21vZGVsID0gbG1lcihyZXNwb25zZSB+IHBjNCAqIHBlcmNlbnRpbGUgKyAoMXxuaWNoZV9uYW1lKSwgZGF0YT1tZXJsaW5fc3BlY2llc19kYXRhKQphbm92YShtZXJsaW5fcGM0X21vZGVsKQpzdW1tYXJ5KG1lcmxpbl9wYzRfbW9kZWwpCmBgYAoKYGBge3J9CnBjX2F4aXNfZmlndXJlKGJpcmRsaWZlX3NwZWNpZXNfZGF0YSkKYGBgCgpgYGB7cn0KZ2dwbG90KG1lcmxpbl9zcGVjaWVzX2RhdGEsIGFlcyh4ID0gcmVzcG9uc2UsIHkgPSBpc19ub2N0dXJuYWwsIGNvbG9yID0gcGVyY2VudGlsZSkpICsgZ2VvbV9ib3hwbG90KCkgKyB0aGVtZV9idygpCmBgYAoKYGBge3J9Cm1lcmxpbl9ub2N0dXJuYWxfYW5vdmEgPC0gYW92KHJlc3BvbnNlfmlzX25vY3R1cm5hbCArIHBlcmNlbnRpbGUgKyBFcnJvcihuaWNoZV9uYW1lKSwgZGF0YT1tZXJsaW5fc3BlY2llc19kYXRhKQpzdW1tYXJ5KG1lcmxpbl9ub2N0dXJuYWxfYW5vdmEpCgptZXJsaW5fbm9jdHVybmFsX2Fub3ZhX2kgPC0gYW92KHJlc3BvbnNlfmlzX25vY3R1cm5hbCAqIHBlcmNlbnRpbGUgKyBFcnJvcihuaWNoZV9uYW1lKSwgZGF0YT1tZXJsaW5fc3BlY2llc19kYXRhKQpzdW1tYXJ5KG1lcmxpbl9ub2N0dXJuYWxfYW5vdmFfaSkKYGBgCgpgYGB7cn0KZ2dwbG90KGJpcmRsaWZlX3NwZWNpZXNfZGF0YSwgYWVzKHggPSByZXNwb25zZSwgeSA9IGlzX25vY3R1cm5hbCwgY29sb3IgPSBwZXJjZW50aWxlKSkgKyBnZW9tX2JveHBsb3QoKSArIHRoZW1lX2J3KCkKYGBgCgpgYGB7cn0KYmlyZGxpZmVfbm9jdHVybmFsX2Fub3ZhIDwtIGFvdihyZXNwb25zZX5pc19ub2N0dXJuYWwgKyBwZXJjZW50aWxlICsgRXJyb3IobmljaGVfbmFtZSksIGRhdGE9YmlyZGxpZmVfc3BlY2llc19kYXRhKQpzdW1tYXJ5KGJpcmRsaWZlX25vY3R1cm5hbF9hbm92YSkKCmJpcmRsaWZlX25vY3R1cm5hbF9hbm92YV9pIDwtIGFvdihyZXNwb25zZX5pc19ub2N0dXJuYWwgKiBwZXJjZW50aWxlICsgRXJyb3IobmljaGVfbmFtZSksIGRhdGE9YmlyZGxpZmVfc3BlY2llc19kYXRhKQpzdW1tYXJ5KGJpcmRsaWZlX25vY3R1cm5hbF9hbm92YV9pKQpgYGAKCmBgYHtyfQpnZ3Bsb3QobWVybGluX3NwZWNpZXNfZGF0YSwgYWVzKHggPSB0b3RhbF9zcGVjaWVzLCB5ID0gbG9nKHJlc3BvbnNlKSwgY29sb3IgPSBwZXJjZW50aWxlKSkgKyBnZW9tX3BvaW50KGFscGhhID0gMC41KSArIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRkFMU0UpICsgdGhlbWVfYncoKQpgYGAKCmBgYHtyfQptZXJsaW5fc3BlY2llc19jb3VudF9tb2RlbCA9IGxtZXIocmVzcG9uc2UgfiB0b3RhbF9zcGVjaWVzICogcGVyY2VudGlsZSArICgxfG5pY2hlX25hbWUpLCBkYXRhPW1lcmxpbl9zcGVjaWVzX2RhdGEpCmFub3ZhKG1lcmxpbl9zcGVjaWVzX2NvdW50X21vZGVsKQpzdW1tYXJ5KG1lcmxpbl9zcGVjaWVzX2NvdW50X21vZGVsKQpgYGAKCmBgYHtyfQpiaXJkbGlmZV9zcGVjaWVzX2NvdW50X21vZGVsID0gbG1lcihyZXNwb25zZSB+IHRvdGFsX3NwZWNpZXMgKiBwZXJjZW50aWxlICsgKDF8bmljaGVfbmFtZSksIGRhdGE9YmlyZGxpZmVfc3BlY2llc19kYXRhKQphbm92YShiaXJkbGlmZV9zcGVjaWVzX2NvdW50X21vZGVsKQpzdW1tYXJ5KGJpcmRsaWZlX3NwZWNpZXNfY291bnRfbW9kZWwpCmBgYAoKYGBge3J9Cm1lcmxpbl9zcGVjaWVzX2RhdGEkcHJlc2VudCA8LSBtZXJsaW5fc3BlY2llc19kYXRhJHJlc3BvbnNlID4gMApgYGAKCmBgYHtyfQpnZ3Bsb3QobWVybGluX3NwZWNpZXNfZGF0YSwgYWVzKHggPSBsb2codG90YWxfc3BlY2llcyksIHkgPSBwcmVzZW50LCBjb2xvciA9IHBlcmNlbnRpbGUpKSArIGdlb21fYm94cGxvdCgpICsgdGhlbWVfYncoKQpgYGAKCmBgYHtyfQptZXJsaW5fcHJlc2VudF9tb2RlbCA9IGxtZXIocHJlc2VudCB+IGxvZyh0b3RhbF9zcGVjaWVzKSAqIHBlcmNlbnRpbGUgKyAoMXxuaWNoZV9uYW1lKSwgZGF0YT1tZXJsaW5fc3BlY2llc19kYXRhKQphbm92YShtZXJsaW5fcHJlc2VudF9tb2RlbCkKc3VtbWFyeShtZXJsaW5fcHJlc2VudF9tb2RlbCkKYGBgCgoKCgo=